use std::ffi::{CStr, CString};
use std::os::raw::{c_char, c_void};
use std::ptr;

trait IQHelloTrait {}

// 定义与 C 头文件匹配的 IQHello 类型
#[repr(C)]
pub struct IQHello {
    _private: [u8; 0], // 不透明类型
}

// Rust 实现结构体
struct RustHelloImpl {
    message: CString, // 使用CString保证以null结尾
}

// 导出函数实现
#[no_mangle]
pub extern "C" fn impl_t() -> i32 {
    return 1; // C 类型插件
}

#[no_mangle]
pub extern "C" fn createIQHello() -> *mut IQHello {
    // 在Rust堆上分配内存
    let impl_ = Box::new(RustHelloImpl {
        message: CString::new("Hello, World!(Rust)").unwrap(),
    });

    // 转换为不透明指针
    Box::into_raw(impl_) as *mut IQHello
}

#[no_mangle]
pub extern "C" fn deleteIQHello(ptr: *mut IQHello) {
    if ptr.is_null() {
        return;
    }

    // 将指针转换回Box，Rust会自动释放内存
    unsafe {
        let _ = Box::from_raw(ptr as *mut RustHelloImpl);
    }
}

#[no_mangle]
pub extern "C" fn getHello(ptr: *const IQHello) -> *const c_char {
    if ptr.is_null() {
        return ptr::null();
    }

    let impl_ = unsafe { &*(ptr as *const RustHelloImpl) };
    impl_.message.as_ptr()
}
